using System;
using System.Collections.Generic;
using ServiceStack.Redis;
using MxNetwork;
using GameTools;
using PuSuoPai;

namespace DTFight
{
	public class ClientData
	{
        static int curServerDbIndex = -1;
        static int curComunicationDbIndex = -1;
        static int curPaymentDbIndex = -1;

		public int ChannelID = 0;
        public uint serverId = 1;
        public string version = "";
        public string SdkName = "";
        public string SdkToken = "";
		public string UserName = "";
		public string CharName = "";
		public string IP = "";

		public PlayerData Player = null;

		ServiceStack.Redis.IRedisClient	mRedis = null;

        bool mIsDirty = false;

		public ClientData (int channelID, string userName)
		{
			ChannelID = channelID;
			UserName = userName;

			//Connect ();
		}

		~ClientData()
		{
		}

		public ServiceStack.Redis.IRedisClient GetRedis()
		{
            int idx = (int)(serverId % 100) - 1;
//            if (curServerDbIndex != idx)
//            {
//                mRedis.ChangeDb(idx);
//                curServerDbIndex = idx;
//            }

            return SSRedisClient.Instance().GetRedis(idx);
		}

		public ServiceStack.Redis.IRedisClient GetRedisCommunication()
        {
            int idx = (int)(serverId % 100) - 1;
//            if (curComunicationDbIndex != idx)
//            {
//                SSRedisClient.Instance().GetRedisCommunication().ChangeDb(idx);
//                curComunicationDbIndex = idx;
//            }

            return SSRedisClient.Instance().GetRedisCommunication(idx);
        }

		public ServiceStack.Redis.IRedisClient GetRedisPayment()
        {
            int idx = (int)(serverId % 100) - 1;
//            if (curPaymentDbIndex != idx)
//            {
//                SSRedisClient.Instance().GetRedisPayment().ChangeDb(idx);
//                curPaymentDbIndex = idx;
//            }

            return SSRedisClient.Instance().GetRedisPayment(idx);
        }

		public void Connect()
		{
			//mRedis = SSRedisClient.Instance().GetRedis();
		}

		public void Disconnect()
		{
			mRedis = null;
		}

        public void SetDirty()
        {
            mIsDirty = true;
        }

        public bool IsDirty()
        {
            return mIsDirty;
        }
	}

	public class ClientMgr
	{
		static ClientMgr mInstance = new ClientMgr();
		static public ClientMgr Instance() { return mInstance; }

		Dictionary<int, ClientData>	mClientDatas = new Dictionary<int, ClientData>();

		public void Init()
		{
			NetworkDispatcher.Instance.OnConnectInfo += OnClientConnect;
			NetworkDispatcher.Instance.OnDisconnectInfo += OnClientDisconnect;
		}

		public void Destroy()
		{
			NetworkDispatcher.Instance.OnConnectInfo -= OnClientConnect;
			NetworkDispatcher.Instance.OnDisconnectInfo -= OnClientDisconnect;

			mInstance = null;
		}

		void OnClientConnect(int channelID)
		{
            ClientData client = new ClientData(channelID, "");

            AddClient (client);
		}

		void OnClientDisconnect(int channelID)
		{
            ClientData client = GetClient(channelID);
            if (client != null)
            {
                //Log.WriteLog("Disconnect Client: " + client.IP);

				RemoveClient (channelID);
            }
		}

		public ClientData GetClient(int channelID)
		{
			if (mClientDatas.ContainsKey(channelID))
			{
				return mClientDatas[channelID];
			}

			return null;
		}

		public ClientData GetClient(string charName)
		{
			foreach (var clt in mClientDatas) {
				if (clt.Value.CharName.Equals (charName))
					return clt.Value;
			}

			return null;
		}

		public void AddClient(ClientData client)
		{
			if (mClientDatas.ContainsKey(client.ChannelID))
			{
				mClientDatas[client.ChannelID].Disconnect();
				return;
			}

			mClientDatas.Add (client.ChannelID, client);
		}

		public void RemoveClient(int channelID)
		{
			if (mClientDatas.ContainsKey (channelID)) {
				mClientDatas[channelID].Disconnect();
				mClientDatas.Remove (channelID);
			}
		}

		public void DisconnectClient(int channelID)
		{
			ClientData client = GetClient(channelID);
			if (client != null)
			{
				Log.WriteLog("Disconnect Client: " + client.IP);

				RemoveClient (channelID);

                MxNetworkManager.GetInstance ().CloseChannel (channelID);
			}
		}

        public void RemoveOldClient(ClientData client)
        {
            foreach (var clt in mClientDatas) {
                if (clt.Value.serverId == client.serverId && clt.Value.UserName.Equals(client.UserName) && clt.Value.SdkName.Equals(client.SdkName)
                    && clt.Value.ChannelID != client.ChannelID)
                {
                    MxNetworkManager.GetInstance ().CloseChannel (clt.Value.ChannelID);
                    mClientDatas.Remove (clt.Value.ChannelID);
                    Log.WriteLog("RemoveOldClient: " + client.IP + ":" + client.ChannelID.ToString());

                    return;
                }
            }
        }
	}
}

